import asyncio
import os
import shutil
import tarfile

# from datetime import datetime, timedelta, date
from datetime import datetime, date
import logging
import logging.handlers
from sanic.log import logger


def access_filter(record):
    """
    access_filter
    """
    if hasattr(record, "request"):
        record.request_host = "HOST " + record.host + " "
        record.request_url = record.request + " "
        record.request_status = record.status
    else:
        record.request_url = ""
        record.request_host = ""
        record.request_status = ""
    return True


class SizeRotatingFileHandler(logging.handlers.RotatingFileHandler):
    def __init__(self, filename, mode='a', maxBytes=0, backupCount=0, encoding=None, delay=False):
        fpath = os.path.dirname(filename)
        if not os.path.exists(fpath):
            os.makedirs(fpath)
        logging.handlers.RotatingFileHandler.__init__(self, filename, mode, maxBytes, backupCount, encoding, delay)


async def create_tar_gz(file_paths, output_filename):
    with tarfile.open(output_filename, "w:gz") as tar:
        for file_path in file_paths:
            if not os.path.exists(file_path):
                continue
            arcname = os.path.basename(file_path)
            tar.add(file_path, arcname=arcname)  # 将每个文件添加到tar文件中


async def delete_directory_contents(directory):
    for filename in os.listdir(directory):
        file_path_temp = os.path.join(directory, filename)
        if os.path.isfile(file_path_temp):
            os.remove(file_path_temp)
        elif os.path.isdir(file_path_temp):
            shutil.rmtree(file_path_temp, ignore_errors=True)


async def delete_folders(folder_paths):
    for folder_path in folder_paths:
        if not os.path.exists(folder_path):
            continue
        await delete_directory_contents(folder_path)
        shutil.rmtree(folder_path)


def check_trigger_date(interval_day):
    # 设置锚点日期
    anchor_date = date(2000, 1, 1)

    # 获取当前日期
    today = date.today()

    # 计算距离锚点日期的天数
    days_since_anchor = (today - anchor_date).days

    # 判断是否是触发时间
    return bool(days_since_anchor % interval_day == 0)


def setup_logger(app):
    if not os.path.exists(app.config.LOG_FILE_PATH):
        os.mkdir(app.config.LOG_FILE_PATH)

    # 1兆字节(mb)=1048576字节(b)
    current_time = datetime.now()
    handler = SizeRotatingFileHandler(
        filename=os.path.join(
            app.config.LOG_FILE_PATH,
            f"{app.config.LOG_FILE_NAME}-{current_time.strftime('%Y-%m-%d')}",
            f"{app.config.LOG_FILE_NAME}.log"
        ),
        maxBytes=app.config.LOG_MAXBYTES,
        backupCount=app.config.LOG_BACKUPCOUNT,
        mode="a+"
    )

    # 日志格式
    formatter = logging.Formatter(app.config.LOG_FORMATTER)
    handler.setFormatter(formatter)

    # 添加filter
    handler.addFilter(access_filter)

    return handler


async def monitor_log_status(app):
    logger.info('监控日志状态 Logging info...')
    while True:
        try:
            sign = False
            # output_file_count = int(getattr(app.config, 'LOG_ARCHIVING_CYCLE', 7))

            current_time = datetime.now()
            # sign_dir = os.path.join(app.config.LOG_FILE_PATH,
            #                         current_time.strftime('%Y-%m-%d'))
            sign_dir = app.config.LOG_FILE_PATH
            if not os.path.exists(sign_dir):
                sign = True

            if sign:
                logger.info('----- 开始切换新日志目录 -----')
                handlers = logger.handlers
                for handler in handlers:
                    if isinstance(handler, SizeRotatingFileHandler):
                        handler.close()
                        logger.handlers.remove(handler)

                handler = setup_logger(app)

                handler.baseFilename = os.path.join(
                    app.config.LOG_FILE_PATH,
                    f"{app.config.LOG_FILE_NAME}-{current_time.strftime('%Y-%m-%d')}",
                    f"{app.config.LOG_FILE_NAME}.log"
                )
                if not os.path.exists(os.path.dirname(handler.baseFilename)):
                    os.makedirs(os.path.dirname(handler.baseFilename))

                handler.stream = open(handler.baseFilename, 'a+', encoding='utf-8')
                logger.addHandler(handler)

                # file_count_day_dir_name = (current_time - timedelta(days=output_file_count)).strftime('%Y-%m-%d')
                # is_trigger_date = check_trigger_date(interval_day=output_file_count)
                # if is_trigger_date:
                #     output_file_dir = os.path.join(app.config.LOG_OUTPUT_NAME)
                #     if not os.path.exists(output_file_dir):
                #         os.makedirs(output_file_dir)
                #     logger.info(f"------ 开始归档{output_file_count}天日志 ------")
                #     file_paths = []
                #     for i in range(output_file_count, 0, -1):
                #         temp_name = (current_time - timedelta(days=i)).strftime('%Y-%m-%d')
                #         temp_dir = os.path.join(app.config.LOG_FILE_PATH, temp_name)
                #         file_paths.append(temp_dir)
                #
                #     output_filename = f"{app.config.LOG_OUTPUT_NAME}/cmp_paas_vmware-{file_count_day_dir_name}-{(current_time - timedelta(days=1)).strftime('%Y-%m-%d')}.tar.gz"
                #     await create_tar_gz(file_paths=file_paths, output_filename=output_filename)
                #     await delete_folders(file_paths)

        except Exception as e:
            logger.error(e)
        finally:
            await asyncio.sleep(10)
